---
title: ContentApp
description: The ContentApp component is the root component for building a content-driven site.
---

---

The `ContentApp` component is the root component for building a content-driven site. It controls and sets up the overall content renderin pipeline, from loading the content to rendering it.

It is recommended to use the `ContentApp` component as the root component of your app like this:

```dart
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_content/jaspr_content.dart';

import 'jaspr_options.dart';

void main() {
  Jaspr.initializeApp(options: defaultJasprOptions);

  runApp(ContentApp(
    parsers: [
      MarkdownParser(), // Parses markdown files
    ],
    // ... More configuration here
  ));
}
```

With this simple setup, using the default `ContentApp()` constructor, there is already a bunch of stuff happening behind the scenes:

1. The app analyzes the 'content' directory in your projects and builds a routing table of all files and folders.
   For example:
   - a file `content/index.md` will be available at `/`
   - a file `content/guides/routing.md` will be available at `guides/routing/`
2. The app will parse the markdown content of each file and render it into a Jaspr component, including some basic theming and typographic styles.  
   - 2.1. If the file contains frontmatter data, it too will be parsed. Data like a 'title' or 'description' will be rendered as html meta tags.
3. When building in static mode, the app will generate static html files for each markdown file at build time.
4. During development, the app watches the 'content' directory for changes and updates the routing table and content accordingly.

## ContentApp()

The default `ContentApp()` constructor is a good starting point for simple content-driven sites. It provides a basic setup for parsing and rendering content from the local filesystem and is easy to setup.

<Card title="Properties" icon="sliders">
  <Property name="directory" type="String">
    The directory to load pages from. This is relative to the root of your project. Defaults to `content`.
  </Property>

  ---

  <Property name="eagerlyLoadAllPages" type="bool">
    Whether to eagerly load all pages at startup. This is needed when a page may depend on other pages, such as when rendering a collection of sub-pages. Defaults to `false`.
  </Property>

  ---

  <Property name="enableFrontmatter" type="bool">
    Whether to enable frontmatter parsing for pages. Defaults to `true`.
  </Property>

  ---

  <Property name="dataDirectory" type="String">
    The directory to load data files from. This is relative to the root of your project. Defaults to `content/_data`.
  </Property>

  ---

  <Property name="templateEngine" type="TemplateEngine">
    An optional [TemplateEngine](/content/concepts/templating) to preprocess a page's content. This is useful for injecting data into the content before parsing.
  </Property>

  ---

  <Property name="parsers" type="List&lt;PageParser&gt;">
    A list of [PageParser](/content/concepts/page_parsing) to use for parsing the page content. Each parser may be responsible for a file type like markdown, html, etc.
  </Property>

  ---

  <Property name="extensions" type="List&lt;PageExtension&gt;">
    A list of [PageExtension](/content/concepts/page_extensions) to use for processing the parsed page nodes. Each extension may add or modify the nodes of the page. Extensions are applied in the order they are listed.
  </Property>

  ---

  <Property name="components" type="List&lt;CustomComponent&gt;">
    A list of [CustomComponent](/content/concepts/custom_components) to use for rendering the page.
  </Property>

  ---

  <Property name="layouts" type="List&lt;PageLayout&gt;">
    A list of [PageLayout](/content/concepts/page_layouts) to use for building the page. When more than one layout is provided, the layout to use is determined by the 'layout' key in the page data. Therefore a page can choose its layout by setting 'layout: ___' in its frontmatter. When no key is set or matching, the first provided layout is used.
  </Property>

  ---

  <Property name="theme" type="ContentTheme">
    The [ContentTheme](/content/concepts/theming) to use for the pages.
  </Property>
</Card>

Based on its properties the `ContentApp()` constructor creates a default `FilesystemLoader` and `FilesystemDataLoader`. It also provides the same configuration to all pages.

For even more control over the content loading and rendering pipeline, you can use the `ContentApp.custom()` constructor.

## ContentApp.custom()

The `ContentApp.custom()` constructor allows you to:

- switch out the default `FilesystemLoader` with one or multiple alternative [`RouteLoader`s](/content/concepts/route_loading), for example the `GitHubLoader` to load content from a GitHub repository instead of a local directory.

- configure the `ConfigResolver` to use different configurations for different pages.

- add a `routeBuilder` to customize the main `Router` component like adding additional routes or inserting custom components above the router.

<Card title="Properties" icon="sliders">
  <Property name="loaders" type="List&lt;RouteLoader&gt;">
    A list of [RouteLoader](/content/concepts/route_loading) to load pages from.
  </Property>

  ---

  <Property name="eagerlyLoadAllPages" type="bool">
    Whether to eagerly load all pages at startup. This is needed when a page may depend on other pages, such as when rendering a collection of sub-pages. Defaults to `false`.
  </Property>

  ---

  <Property name="configResolver" type="ConfigResolver">
    A function resolve the configuration for a page based on its url. Use `PageConfig.all` to resolve the same config for all pages.
  </Property>

  ---

  <Property name="routeBuilder" type="RouteBuilder">
    A custom builder function to use for building the main [`Router`](/api/components/router) component. This can be used to customize the `Router` component like add additional routes or inserting components above the router.
  </Property>
</Card>